﻿/*
 * scadashow.cpp
 *
 *  Created on: 2017年3月24日
 *      Author: work
 */

#include <iostream>
#include <boost/program_options.hpp>
#include <dm/scada/scada.hpp>

#include <dm/scada/devicemgr.hpp>
#include <dm/scada/statusmgr.hpp>
#include <dm/scada/discretemgr.hpp>
#include <dm/scada/measuremgr.hpp>
#include <dm/scada/cumulantmgr.hpp>
#include <dm/scada/remotectlmgr.hpp>
#include <dm/scada/parametermgr.hpp>
#include <dm/scada/actionmgr.hpp>

#include <dm/scada/logicdevicemgr.hpp>
#include <dm/scada/logicdevice.hpp>

#include <dm/scada/devicestate.hpp>

#include <dm/datetime.hpp>

using namespace std;
using namespace boost::program_options;

static const unsigned int colIdSize = 8;
static const unsigned int colDescSize = 30;
int main( int argc,char* argv[] ){
	options_description desc("【DM2016帮助文档】\n SCADA查询工具。\n\t基于DM2016系统构建\n支持以下选项");

	options_description opts_generic("一般选项");
	opts_generic.add_options()
			("help,h","显示本帮助信息")
			("version,v","显示版本及编译信息")
			;
	desc.add(opts_generic);

	options_description opts_cmd("命令选项");
	opts_cmd.add_options()
			("init","复位SCADA系统")
			("config","查看配置信息")
			("data","查看实时数据信息")
			;
	desc.add(opts_cmd);

	options_description opts_filter("过滤选项");
	opts_filter.add_options()
			("logic,l","指定逻辑设备。否则为物理设备")
			("device",value<int>(),"设备id。不指定则全部设备")
			("all,a","查看全部信息")
			("status,s","查看状态信息")
			("discrete,d","查看离散信息")
			("measure,m","查看遥测信息")
			("cumulant,c","查看累计量信息")
			("parameter,p","查看参数信息")
			("remoute_ctl,r","查看遥控信息")
			("action","查看动作信息")
			;
	desc.add(opts_filter);

	variables_map vm;
	try{
		store(parse_command_line(argc,argv,desc),vm);
		notify(vm);
	}catch( std::exception& ex ){
		cout << ex.what()<<endl;
		return 1;
	}

	if( vm.count("version") ){
		cout <<"V1.0 构建于 "<<__DATE__<<endl;
		return 1;
	}

	if( vm.count("help") ){
		cout <<desc<<endl;
		return 1;
	}

	if( vm.count("init") ){
		cout <<"复位配置信息...";
		dm::scada::CScada::reset();
		cout <<" 成功."<<endl;

		return 0;
	}

	dm::scada::CStatusMgr& statusMgr = dm::scada::CStatusMgr::ins();
	dm::scada::CDiscreteMgr& discreteMgr = dm::scada::CDiscreteMgr::ins();
	dm::scada::CMeasureMgr& measureMgr = dm::scada::CMeasureMgr::ins();
	dm::scada::CCumulantMgr& cumulantMgr = dm::scada::CCumulantMgr::ins();
	dm::scada::CRemoteCtlMgr& remoteCtlMgr = dm::scada::CRemoteCtlMgr::ins();
	dm::scada::CParameterMgr& parameterMgr = dm::scada::CParameterMgr::ins();
	dm::scada::CActionMgr& actionMgr = dm::scada::CActionMgr::ins();

	dm::scada::CDeviceMgr& deviceMgr = dm::scada::CDeviceMgr::ins();
	dm::scada::CLogicDeviceMgr& logicDeviceMgr = dm::scada::CLogicDeviceMgr::ins();

	cout.fill(' ');
	cout.setf(cout.left);

	if( vm.count("config") ){
		if( vm.count("logic")==0 ){
			for( int i=0;i<deviceMgr.size();++i ){
				if( vm.count("device") && int(deviceMgr.id(i))!=vm["device"].as<int>() )
					continue;

				const dm::scada::SDeviceInfo* deviceInfo = deviceMgr.info(i);

				cout <<i<<"# ";
				deviceMgr.print(i);
				cout <<endl;

				if( deviceInfo->sizeOfStatus>0 && (vm.count("all") || vm.count("status")) ){
					cout <<"* 状态量信息 起始偏移:"<<deviceInfo->posOfStatus<<endl;

					for( int n = 0;n<deviceInfo->sizeOfStatus;++n ){
						cout <<n<<')';
						statusMgr.printInfo(deviceInfo->posOfStatus+n);
						cout <<endl;
					}

					cout <<endl;
				}

				if( deviceInfo->sizeOfDiscrete>0 && (vm.count("all") || vm.count("discrete")) ){
					cout <<"* 离散量信息 起始偏移:"<<deviceInfo->posOfDiscrete<<endl;

					for( int n = 0;n<deviceInfo->sizeOfDiscrete;++n ){
						cout <<n<<')';
						discreteMgr.printInfo(deviceInfo->posOfDiscrete+n);
						cout <<endl;
					}

					cout <<endl;
				}

				if( deviceInfo->sizeOfMeasure>0 && (vm.count("all") || vm.count("measure")) ){
					cout <<"* 测量量信息 起始偏移:"<<deviceInfo->posOfMeasure<<endl;

					for( int n = 0;n<deviceInfo->sizeOfMeasure;++n ){
						cout <<n<<')';
						measureMgr.printInfo( deviceInfo->posOfMeasure+n);
						cout <<endl;
					}

					cout <<endl;
				}

				if( deviceInfo->sizeOfCumulant>0 && (vm.count("all") || vm.count("cumulant")) ){
					cout <<"* 累计量信息 起始偏移:"<<deviceInfo->posOfCumulant<<endl;

					for( int n = 0;n<deviceInfo->sizeOfCumulant;++n ){
						cout <<n<<')';
						cumulantMgr.printInfo( deviceInfo->posOfCumulant+n );
						cout <<endl;
					}

					cout <<endl;
				}

				if( deviceInfo->sizeOfTeleCtl>0 && (vm.count("all") || vm.count("remoute_ctl")) ){
					cout <<"* 远控信息 起始偏移:"<<deviceInfo->posOfTeleCtl<<endl;

					for( int n = 0;n<deviceInfo->sizeOfTeleCtl;++n ){
						cout <<n<<')';
						remoteCtlMgr.printInfo( deviceInfo->posOfTeleCtl+n );
						cout <<endl;
					}

					cout <<endl;
				}

				if( deviceInfo->sizeOfPara>0 && (vm.count("all") || vm.count("parameter")) ){
					cout <<"* 参数信息 起始偏移:"<<deviceInfo->posOfPara<<endl;

					for( int n = 0;n<deviceInfo->sizeOfPara;++n ){
						cout <<n<<')';
						parameterMgr.printInfo( deviceInfo->posOfPara+n );
						cout <<endl;
					}

					cout <<endl;
				}

				if( deviceInfo->sizeOfAction>0 && (vm.count("all") || vm.count("action")) ){
					cout <<"* 动作信息 起始偏移:"<<deviceInfo->posOfAction<<endl;

					for( int n = 0;n<deviceInfo->sizeOfAction;++n ){
						cout <<n<<')';
						actionMgr.printInfo( deviceInfo->posOfAction+n );
						cout <<endl;
					}

					cout <<endl;
				}
			}
		}

		if( vm.count("logic") || vm.count("device")==0 ){
			for( int i=0;i<logicDeviceMgr.size();++i ){
				if( vm.count("device") && int(logicDeviceMgr.id(i))!=vm["device"].as<int>() )
					continue;

				cout <<i<<"* ";
				logicDeviceMgr.print(i);
				cout <<endl;

				dm::scada::CLogicDevice logicDevice;
				logicDevice.initByIndex(i);

				if( logicDevice.statusSize()>0 && (vm.count("all") || vm.count("status")) ){
					cout <<"* 状态量映射表:"<<endl;
					for( int n = 0;n<logicDevice.statusSize();++n ){
						cout <<n<<')';
						statusMgr.printInfo(logicDevice.physicalStatus(n));
						cout <<endl;
					}

					cout <<endl;
				}

				if( logicDevice.discreteSize()>0 && (vm.count("all") || vm.count("discrete")) ){
					cout <<"* 离散量映射表:"<<endl;
					for( int n = 0;n<logicDevice.discreteSize();++n ){
						cout <<n<<')';
						discreteMgr.printInfo(logicDevice.physicalDiscrete(n));
						cout <<endl;
					}

					cout <<endl;
				}

				if( logicDevice.measureSize()>0 && (vm.count("all") || vm.count("measure")) ){
					cout <<"* 测量量映射表:"<<endl;
					for( int n = 0;n<logicDevice.measureSize();++n ){
						cout <<n<<')';
						measureMgr.printInfo(logicDevice.physicalMeasure(n));
						cout <<endl;
					}

					cout <<endl;
				}

				if( logicDevice.cumulantSize()>0 && (vm.count("all") || vm.count("cumulant")) ){
					cout <<"* 累计量映射表:"<<endl;
					for( int n = 0;n<logicDevice.cumulantSize();++n ){
						cout <<n<<')';
						cumulantMgr.printInfo(logicDevice.physicalCumulant(n));
						cout <<endl;
					}

					cout <<endl;
				}

				if( logicDevice.remoteCtlSize()>0 && (vm.count("all") || vm.count("remoute_ctl")) ){
					cout <<"* 远控映射表:"<<endl;
					for( int n = 0;n<logicDevice.remoteCtlSize();++n ){
						cout <<n<<')';
						remoteCtlMgr.printInfo(logicDevice.physicalRemoteCtl(n));
						cout <<endl;
					}

					cout <<endl;
				}

				if( logicDevice.parameterSize()>0 && (vm.count("all") || vm.count("parameter")) ){
					cout <<"* 参数映射表:"<<endl;
					for( int n = 0;n<logicDevice.parameterSize();++n ){
						cout <<n<<')';
						parameterMgr.printInfo(logicDevice.physicalParameter(n));
						cout <<endl;
					}

					cout <<endl;
				}

				if( logicDevice.actionSize()>0 && (vm.count("all") || vm.count("action")) ){
					cout <<"* 动作映射表:"<<endl;
					for( int n = 0;n<logicDevice.actionSize();++n ){
						cout <<n<<')';
						actionMgr.printInfo(logicDevice.physicalAction(n));
						cout <<endl;
					}

					cout <<endl;
				}
			}
		}
	}else if( vm.count("data") ){
		for( int i=0;i<deviceMgr.size();++i ){

			if( vm.count("device") && int(deviceMgr.id(i))!=vm["device"].as<int>() )
				continue;

			cout <<'['<<i<<"]: id="<<deviceMgr.id(i)<<" "<<deviceMgr.desc(i) <<endl;

			const dm::scada::CDeviceState* ds = deviceMgr.state(i);
			const dm::scada::SDeviceInfo* deviceInfo = deviceMgr.info(i);

			cout <<" 设备状态:";
			if( ds->isAlive() )
				cout <<"正常";
			else
				cout <<"停机";

			cout <<" 最后状态:";

			switch( ds->getLastState() ){
			case dm::scada::CDeviceState::ESSysInit:
				cout <<"从未运行";
				break;
			case dm::scada::CDeviceState::ESComConnting:
				cout <<"正在连接";
				break;
			case dm::scada::CDeviceState::ESComConnted:
				cout <<"已经连接";
				break;
			case dm::scada::CDeviceState::ESComFail:
				cout <<"连接失败";
				break;
			case dm::scada::CDeviceState::ESComDiscon:
				cout <<"断开连接";
				break;
			case dm::scada::CDeviceState::ESLocalRun:
				cout <<"本地运行";
				break;
			case dm::scada::CDeviceState::ESLocalStop:
				cout <<"本地允许";
				break;
			}

			cout <<" 更新时刻："<< dm::CDateTime(ds->getLastStateTime().toTimeStamp()).toString();
			cout <<" 接收流量："<< ds->getRxCnt().getCount();
			cout <<" 发送流量："<< ds->getTxCnt().getCount();
			cout <<endl;


			if( vm.count("all") || vm.count("status") ){
				cout <<"* 状态量实时数据"<<endl;
				for( int n = 0;n<deviceInfo->sizeOfStatus;++n ){
					cout <<n<<')';
					statusMgr.printInfoValue(deviceInfo->posOfStatus+n);
					cout <<endl;
				}
				cout <<endl;
			}

			if( vm.count("all") || vm.count("discrete") ){
				cout <<"* 离散量信息: "<<endl;
				for( int n = 0;n<deviceInfo->sizeOfDiscrete;++n ){
					cout <<n<<')';
					discreteMgr.printInfoValue(deviceInfo->posOfDiscrete+n);
					cout <<endl;
				}
				cout <<endl;
			}

			if( vm.count("all") || vm.count("measure") ){
				cout <<"* 测量量信息: "<<endl;
				for( int n = 0;n<deviceInfo->sizeOfMeasure;++n ){
					cout <<n<<')';
					measureMgr.printInfoValue(deviceInfo->posOfMeasure+n);
					cout <<endl;
				}
				cout <<endl;
			}

			if( vm.count("all") || vm.count("cumulant") ){
				cout <<"* 累计量信息: "<<endl;
				for( int n = 0;n<deviceInfo->sizeOfCumulant;++n ){
					cout <<n<<')';
					cumulantMgr.printInfoValue(deviceInfo->posOfCumulant+n);
					cout <<endl;
				}
				cout <<endl;
			}
		}
	}

	return 0;
}


